package org.datacoder.geocoding.datastructures.intervals

import org.datacoder.geocoding.datastructures.geoshapes.*
import org.datacoder.geocoding.datastructures.util.*
import org.datacoder.geocoding.jurisdiction.*

class Buckets implements IntersectingIntervalsFinder {

    private Country us
    private State alaska
    private State hawaii
    private BucketsSubStructure lower48Buckets
    private BucketsSubStructure alaskaBuckets
    private BucketsSubStructure hawaiiBuckets
    int type

    public Buckets(Collection<Jurisdiction> jurisdictions, int type){
        this.type = type
        Set<State> lower48 = State.findAll()
        alaska = State.findByName("AK")
        hawaii = State.findByName("HI")
        if(alaska != null){
            lower48.remove(alaska)
        }
        if(hawaii != null){
            lower48.remove(hawaii)
        }
        Set<Jurisdiction> lower48Jurisdictions = new HashSet<Jurisdiction>(lower48)
        Set<Jurisdiction> alaskaJurisdictions = new HashSet<Jurisdiction>()
        Set<Jurisdiction> hawaiiJurisdictions = new HashSet<Jurisdiction>()
        if(alaska != null){
            alaskaJurisdictions.add(alaska)
        }
        if(hawaii != null){
            hawaiiJurisdictions.add(hawaii)
        }
        for(juris in jurisdictions){
            if(juris instanceof Country){
                us = (Country)juris
            }else if(juris instanceof State){
                continue
            }else if(juris instanceof County){
                if(((County)juris).state == alaska){
                    alaskaJurisdictions.add(juris)
                }else if(((County)juris).state == hawaii){
                    hawaiiJurisdictions.add(juris)
                }else{
                    lower48Jurisdictions.add(juris)
                }
            }else if(juris instanceof Municipality){
                if(((Municipality)juris).state == alaska){
                    alaskaJurisdictions.add(juris)
                }else if(((Municipality)juris).state == hawaii){
                    hawaiiJurisdictions.add(juris)
                }else{
                    lower48Jurisdictions.add(juris)
                }
            }else if(juris instanceof CongressionalDistrict){
                if(((CongressionalDistrict)juris).state == alaska){
                    alaskaJurisdictions.add(juris)
                }else if(((CongressionalDistrict)juris).state == hawaii){
                    hawaiiJurisdictions.add(juris)
                }else{
                    lower48Jurisdictions.add(juris)
                }
            }else if(juris instanceof SenatorialDistrict){
                if(((SenatorialDistrict)juris).state == alaska){
                    alaskaJurisdictions.add(juris)
                }else if(((SenatorialDistrict)juris).state == hawaii){
                    hawaiiJurisdictions.add(juris)
                }else{
                    lower48Jurisdictions.add(juris)
                }
            }else if(juris instanceof RepresentativeDistrict){
                if(((RepresentativeDistrict)juris).state == alaska){
                    alaskaJurisdictions.add(juris)
                }else if(((RepresentativeDistrict)juris).state == hawaii){
                    hawaiiJurisdictions.add(juris)
                }else{
                    lower48Jurisdictions.add(juris)
                }
            }else if(juris instanceof ZipCode){
                if(((ZipCode)juris).state == alaska){
                    alaskaJurisdictions.add(juris)
                }else if(((ZipCode)juris).state == hawaii){
                    hawaiiJurisdictions.add(juris)
                }else{
                    lower48Jurisdictions.add(juris)
                }
            }else if(juris instanceof VotingDistrict){
                if(((VotingDistrict)juris).county.state == alaska){
                    alaskaJurisdictions.add(juris)
                }else if(((VotingDistrict)juris).county.state == hawaii){
                    hawaiiJurisdictions.add(juris)
                }else{
                    lower48Jurisdictions.add(juris)
                }
            }
        }
        lower48Buckets = new BucketsSubStructure(lower48Jurisdictions, lower48, type)
        if(alaska != null){
            Set<Jurisdiction> alaskaSet = new HashSet<Jurisdiction>()
            alaskaSet.add(alaska)
            alaskaBuckets = new BucketsSubStructure(alaskaJurisdictions, alaskaSet, type)
        }
        if(hawaii != null){
            Set<Jurisdiction> hawaiiSet = new HashSet<Jurisdiction>()
            hawaiiSet.add(hawaii)
            hawaiiBuckets = new BucketsSubStructure(hawaiiJurisdictions, hawaiiSet, type)
        }
    }

    public Set<Jurisdiction> findIntersectingIntervals(GeoInterval gi){
        Set<Jurisdiction> jurisdictions = new HashSet<Jurisdiction>()
        jurisdictions.addAll(lower48Buckets.findIntersectingIntervals(gi))
        if(alaska != null){
            jurisdictions.addAll(alaskaBuckets.findIntersectingIntervals(gi))
        }
        if(hawaii != null){
            jurisdictions.addAll(hawaiiBuckets.findIntersectingIntervals(gi))
        }
        if(!jurisdictions.isEmpty()){
            jurisdictions.add(us)
        }
        return jurisdictions
    }
	
}

